#!/bin/bash

source ./config/config

##基础检查函数
wDetail() {
	key=`echo "$2" | sed s/[[:space:]]//g`
	echo -e "$1" >>$result_dir/${key}_detail
}

##wDetail之后进行一次column排版
wDetail_column() {
	key=`echo "$2" | sed s/[[:space:]]//g`
	echo -e "$1" >>$result_dir/${key}_detail
	if [[ $3 == "" ]]; then
	  column -t $result_dir/${key}_detail > $result_dir/temp_${key}_detail
	else
	  column -t -s "$3" $result_dir/${key}_detail > $result_dir/temp_${key}_detail
  fi
	mv -f $result_dir/temp_${key}_detail $result_dir/${key}_detail
}

############## 开始执行巡检，获取操作系统信息 ###############
#检查执行用户
exe_user=`whoami`
echo -e "您当前执行脚本的用户是 \033[31m$exe_user\033[0m "
if [[ $exe_user != 'root' ]];then
	echo "使用非root或非root权限用户执行脚本，在查看/var/log/messages日志或执行lsof命令时可能报权限错误"
fi

##基础检查函数
function wDetail() {
	key=`echo "$2" | sed s/[[:space:]]//g`
	if [[ -z "$1" ]]; then
     echo -e "无" >>$result_dir/${key}_detail
  else
     echo -e "$1" >>$result_dir/${key}_detail
	fi
}

function wResult() {
	result=`echo "$1" | sed s/[[:space:]]//g`
	key=`echo "$2" | sed s/[[:space:]]//g`

	if [[ -e "$result_dir/${key}_result" ]];then
		if [[ $result == "FATAL" ]]; then
			echo "FATAL">$result_dir/${key}_result
		elif [[ $result == "ERROR" ]]; then
			if [[ `grep "FATAL" $result_dir/${key}_result | wc -l` -eq 0 ]]; then
				echo "ERROR">$result_dir/${key}_result
			fi
		elif [[ $result == "WARNING" ]]; then
			if [[ `grep -E "FATAL|ERROR" $result_dir/${key}_result | wc -l` -eq 0 ]]; then
				echo "WARNING">$result_dir/${key}_result
			fi
		elif [[ $result == "NORMAL" ]]; then
			if [[ `grep -E "FATAL|ERROR|WARNING|UNKOWN" $result_dir/${key}_result | wc -l` -eq 0 ]]; then
				echo "NORMAL">$result_dir/${key}_result
			fi
		else
			if [[ `grep -E "FATAL|ERROR|WARNING" $result_dir/${key}_result | wc -l` -eq 0 ]]; then
				echo "UNKOWN">$result_dir/${key}_result
			fi
		fi
	else
		echo $result>$result_dir/${key}_result
	fi
}

cpu_info=''
get_cpu_info() {
	echo -e "#################  CPU架构信息  #################"
	cpu_info=`lscpu`
	wDetail "$cpu_info" cpu_info
}

total_mem_info=''
get_total_mem_info() {
	echo -e "#################  操作系统内存大小信息  #################"
	total_mem_info=`grep MemTotal /proc/meminfo`
	wDetail "$total_mem_info" total_mem_info
}

os_dbuser_expire=''
get_os_root_expire() {
	echo -e "#################  用户过期时间  #################"
	# os_dbuser_expire=$(chage -l root | awk '/Password expires/{print $NF}')
	os_dbuser_expire=`chage -l root`
	wDetail "$os_dbuser_expire" os_dbuser_expire
}

swappiness=''
kernel_shmall=''
kernel_shmmax=''
get_kernel_para() {
	echo -e "#################  内核参数配置  #################"
	sysctl_info=$(sysctl -a 2>/dev/null)
	swappiness=$(sysctl vm.swappiness | awk '{print $NF}')
	kernel_shmall=$(sysctl kernel.shmall | awk '{print $NF}')
	kernel_shmmax=$(sysctl kernel.shmmax | awk '{print $NF}')
	wDetail "swappiness=$swappiness\nkernel_shmall=$kernel_shmall\nkernel_shmmax=$kernel_shmmax\n\n" kernel_para
	wDetail "sysctl的结果如下：\n$sysctl_info" kernel_para

	mem_total=`grep MemTotal /proc/meminfo |awk '{print $2}'`

	let "mymem=mem_total/2"

	shmall_length=`echo "$kernel_shmall" |wc -L`
	mymem_length=`echo "$mymem" |wc -L`
	if [ $swappiness -ne 0 ]; then
		if [ $shmall_length -lt $mymem_length ]; then
			wResult "ERROR" kernel_para
		else
			wResult "WARNING" kernel_para
		fi
	else
		if [ $shmall_length -lt $mymem_length ]; then
			wResult "WARNING" kernel_para
		else
			wResult "NORMAL" kernel_para
		fi
	fi
}

resource_limit_count=''
get_resource_limit() {
	echo -e "#################  资源限制配置  #################"
	resource_limit_detail=`cat /etc/security/limits.conf `
#	resource_limit_count=`echo "$resource_limit_detail" | wc -l`
	wDetail "`cat /etc/security/limits.conf | grep -v ^# | grep -Ev '^$'`" resource_limits

#	if [ $resource_limit_count -eq 0 ];then
#		wResult "FATAL" resource_limits
#	else
#		wResult "NORMAL" resource_limits
#	fi
}

selinux=''
get_selinux() {
	echo -e "#################  selinux配置  #################"
	selinux=$(getenforce)
	selinux_dtl=$(awk '/^\w/' /etc/selinux/config)
	wDetail "$selinux_dtl" selinux
	#wDetail "`cat /etc/selinux/config | grep -v ^# | grep -Ev '^$'`" selinux

	if echo "$selinux" | grep -qwi "Disabled"
	then
		wResult "NORMAL" selinux
	else
		wResult "FATAL" selinux
	fi
}

transparent_hugepage_enabled=''
transparent_hugepage_defrag=''
get_transparent_hugepage() {
	echo -e "#################  透明大页配置  #################"
	transparent_hugepage_enabled=$(grep -Po '(?<=\[)\w+(?=\])' /sys/kernel/mm/transparent_hugepage/enabled)
	transparent_hugepage_defrag=$(grep -Po '(?<=\[)\w+(?=\])' /sys/kernel/mm/transparent_hugepage/defrag)
	wDetail "transparent_hugepage_enabled\n`cat /sys/kernel/mm/transparent_hugepage/enabled`\n\ntransparent_hugepage_defrag\n`cat /sys/kernel/mm/transparent_hugepage/defrag`" transparent_hugepage

#	if [[ $transparent_hugepage_enabled == 'never' ]];then
#		if [[ $transparent_hugepage_defrag == 'never' ]];then
#			wResult "NORMAL" transparent_hugepage
#		else
#			wResult "FATAL" transparent_hugepage
#		fi
#	else
#		wResult "FATAL" transparent_hugepage
#	fi
}

hugepage=''
get_hugepage() {
	echo -e "#################  标准大页配置  #################"
	hugepage=`grep HugePages_Total /proc/meminfo | awk -F':' '{print $2}' | sed s/[[:space:]]//g`
	wDetail "`cat /proc/meminfo`" hugepage

	if [ $hugepage -eq 0 ];then
		wResult "NORMAL" hugepage
	else
		wResult "FATAL" hugepage
	fi
}

avail_mem_percent=''
get_mem_info() {
	echo -e "#################  内存使用情况  #################"
	mem_total=`grep MemTotal /proc/meminfo |awk '{ print $2}'`
	avail_mem=`grep MemAvailable /proc/meminfo |awk '{ print $2}'`
	avail_mem_percent=`awk 'BEGIN{printf "%0.2f","'$avail_mem'"/"'$mem_total'"}'`
	wDetail "`free -m`" mem_info

	my_mem=`awk 'BEGIN{print("'$avail_mem_percent'"*100)}'`

	if [ $my_mem -ge 9000 ];then
		wResult "FATAL" mem_info
	elif [ $my_mem -ge 8000 ];then
		wResult "WARNING" mem_info
	else
		wResult "NORMAL" mem_info
	fi
}

cpu_used=''
get_cpu_used() {
	echo -e "#################  cpu使用率  #################"
	cpu_idle=`top -b n1 |grep Cpu |awk -F',' '{print $4}'|awk '{print $1}'|sed s/[[:space:]]//g`
	cpu_used=`awk 'BEGIN{printf "%0.2f",100-"'$cpu_idle'"}'`
	wDetail "`top -bn1 -o "%CPU"|sed  -n '1,17p'`" cpu

	my_cpu=`awk 'BEGIN{print("'$cpu_used'"*100)}'`

	if [ $my_cpu -ge 9000 ];then
		wResult "FATAL" cpu
	elif [ $my_cpu -ge 8000 ];then
		wResult "WARNING" cpu
	else
		wResult "NORMAL" cpu
	fi
}

root_disk_used=''
data_disk_used=''
backup_disk_used=''
io_mean=0
get_disk_info() {
	echo -e "#################  硬盘使用情况  #################"
	df_info=`df -Th`
	root_disk_used=`df -h | grep /$ | sed 's/%//' |awk '{print $5}'`
	my_root=`echo $root_disk_used|sed 's/%//g'`

	disk_fatal=`df -h | grep -v "Filesystem" | grep -v "文件系统" | sed 's/%//'| awk '{if($5>80) print $1}'`
	warning_fatal=`df -h | grep -v "Filesystem"| grep -v "文件系统" | sed 's/%//'| awk '{if($5>75) print $1}'`
	if [[ -n $disk_fatal ]];then
		wResult "FATAL" disk
	elif [[ -n $warning_fatal ]];then
		wResult "WARNING" disk
	else
		wResult "NORMAL" disk
	fi

	wDetail "根目录的磁盘使用率为: $my_root%" disk
	wDetail "$df_info" disk
}


get_net_io() {
	echo -e "#################  网络IO  #################"
	# 网络IO应较平稳，此项难以判断，仅为完善系统资源指标而收集

	net_io_detail_origin=`top -bn 3 | grep Cpu | awk -F"%" '{print $2}'`
	net_io_mean=`echo "$net_io_detail_origin" | awk '{sum+=$12} END {print sum/NR}'`
	disk_io_mean=`echo "$net_io_detail_origin" | awk '{sum+=$10} END {print sum/NR}'`
	# net_io_detail=`echo "$net_io_detail_origin" | sed s/[[:space:]]/%20/g | sed s/:/%3A/g | sed s/,/%2C/g`

	wDetail "平均网络io=$net_io_mean\n平均磁盘io=$disk_io_mean\n" net
	wDetail "$net_io_detail_origin" net
}

backup_cron_list=''
get_cron() {
	echo -e "#################  定时任务  #################"
	# if [[ "$exe_user" == "root" ]];then
	# 	backup_cron_list=`crontab -l| grep -v '^#' | grep -i backup`
	# else
	# 	backup_cron_list=`crontab -l -u ${DB_USER} | grep -v '^#' | grep -i backup`
	# fi
	# crontab_list=`crontab -l`

	# if [[ -n "$backup_cron_list" ]]||[[ -n "$crontab_list" ]];then

	#     if [[ ${backup_cron_list} == '' ]];then
	#        wResult "FATAL" crontab
	# 	   wDetail "crontab没有发现定时backup任务，请检查!" crontab
	#     else
	#        wResult "NORAML" crontab
	#     fi

	#     crontab_sh_list=`echo "$crontab_list" | awk '{print $NF}' | awk -F"." '{if($NF=="sh"){print $0}}'`
	#     for crontab_sh in ${crontab_sh_list[@]}
	#     do
	#         wDetail "$crontab_sh\n" crontab
	#     done

	#     cron_sh_list=`crontab -l -u ${DB_USER} |awk -F ' ' '{ print $NF}' |grep "sh"`
	#     for cron_sh in ${cron_sh_list[@]}
	#     do
	#         wDetail "\n获取系统定时任务脚本 $cron_sh 内容\n" crontab
	#         wDetail "`cat $cron_sh`" crontab
	#     done

	# else
	# 	wResult "FATAL" crontab
	# 	wDetail "服务器没有定时任务，请检查!" crontab
	# fi
	if [[ "$exe_user" == "root" ]];then
		cron_list=`crontab -l | grep -v '^[[:space:]]*#'`
		cron_list="$exe_user用户:\n$cron_list"
		if [[ -n $cron_list ]];then
			wDetail "$cron_list" crontab
		else
			wDetail "$exe_use用户无定时任务或是无权限查询。" crontab
		fi
		wResult "NORMAL" crontab

	else
		cron_list=`crontab -l | grep -v '^[[:space:]]*#'`
		cron_list_db_user=`crontab -l -u root | grep -v '^[[:space:]]*#'`
		if [[ -n $cron_list ]]||[[ -n $cron_list_db_user ]];then
			if [[ -n $cron_list_db_user ]]; then
				cron_list="root用户:\n$cron_list_db_user\n\n$exe_user用户:\n$cron_list\n"
			else
				cron_list="$exe_user用户:\n$cron_list\n"
			fi
			wResult "NORMAL" crontab
			wDetail "$cron_list" crontab
		else
			wResult "FATAL" crontab
			wDetail "服务器没有定时任务，请检查!" crontab
		fi
	fi

}

restart_time=''
get_restart_time() {
	echo -e "#################  主机重启时间  #################"
	restart_time=`date -d "$(awk -F. '{print $1}' /proc/uptime) second ago" +"%Y-%m-%d %H:%M:%S"`
	restart_time_seconds=`date -d "$(awk -F. '{print $1}' /proc/uptime) second ago" +"%s"`
	now_seconds=`date +"%s"`

	restart_day=`echo $((($now_seconds-$restart_time_seconds) / 60 / 60 / 24))`

	wDetail "上次重启距今已过去 $restart_day 天!!\n" reboot
	wDetail "restart_time=$restart_time\n `last | grep -i reboot | head -1`" reboot
}

get_sys_log() {
	echo -e "#################  系统日志异常  #################"
	if [[ $exe_user == "root" ]];then
		syslog=`grep -iE "FATAL|ERROR|OOM|allocate memory" /var/log/messages | tail -500`
		wDetail "$syslog" syslog
		wDetail "查看系统日志中发生FATAL、ERROR或内存泄露报错的信息！" syslog
		if [[ -n $syslog ]];then
			wResult "WARNING" syslog
		else
			wResult "NORMAL" syslog
			wDetail "系统日志没有ERROR或OOM报错信息" syslog
		fi
	else
		wResult "NORMAL" syslog
		wDetail "非root用户不检查该项" syslog
	fi
}

warning_user_list=''
fatal_user_list=''
wf_temp=0
get_os_user_expire() {
	echo -e "#################  OS用户密码过期检查  #################"
	if [[ $exe_user == "root" ]];then
		while IFS=: read -r user _ uid _; do
			if [ "$uid" -ge 1000 ]; then
				password_expires=$(chage -l "$user" | awk -F: '/Password expires/ {print $2}')

				if [ "$password_expires" != " never" ]; then
					password_expires_date=$(date -d "$password_expires" +%s)
					current_date=$(date +%s)
					days_remaining=$((($password_expires_date - $current_date) / 86400))

					if [ $current_date -gt $password_expires_date ]; then
						wDetail "$user 密码已经过期" os_user_expire
						[ -z "$fatal_user_list" ] && fatal_user_list="$user" || fatal_user_list="$fatal_user_list,$user"
					else
						wDetail "$user 密码还有 $days_remaining 天过期" os_user_expire
						if [ $days_remaining -le 90 ]; then
							[ -z "$warning_user_list" ] && warning_user_list="$user" || warning_user_list="$warning_user_list,$user"
						fi
					fi
				else
					wDetail "$user 密码不会过期" os_user_expire
				fi
			fi
		done < /etc/passwd


		if [ -n "$warning_user_list" ]; then
			sed -i "1s/^/存在用户密码过期时间不足90天：$warning_user_list\n/" "$result_dir/os_user_expire_detail"
			wf_temp=1
		fi

		if [ -n "$fatal_user_list" ]; then
			sed -i "1s/^/存在密码已过期用户：$fatal_user_list\n/" "$result_dir/os_user_expire_detail"
			wf_temp=2
		fi

		if [ "$wf_temp" -eq 0 ]; then
			wResult "NORMAL" os_user_expire
		elif [ "$wf_temp" -eq 1 ]; then
			wResult "WARNING" os_user_expire
		elif [ "$wf_temp" -eq 2 ]; then
			wResult "WARNING" os_user_expire
		fi


	else
		echo "使用非root用户执行脚本，跳过OS用户密码过期检查"
		wDetail "使用非root用户进行巡检，跳过该项检查\n" os_user_expire
		wResult "NORMAL" os_user_expire
	fi
}

# 推送
mc_checkfile_push() {
#    info "copy checkfile to mc server"
    local mc_name=$1
    local mc_host=$2
    local mc_access=$3
    local mc_secret=$4
    local file_output=$5

    if [ -f "${result_dir}/${file_output}" ]; then
       mc --insecure config host add ${mc_name} ${mc_host} ${mc_access} ${mc_secret}
       mc --insecure mb ${mc_name}/check/ --ignore-existing
       mc --insecure cp ${result_dir}/${file_output} ${mc_name}/check/${file_output}
       sleep 1

       if [[ ${EXPIRY_DAYS} != "" ]]; then
          mc ilm add --expiry-days ${EXPIRY_DAYS} ${mc_name}/check/${file_output}
       fi

    else
      error "File ${result_dir}/${file_output} didn't exist"
    fi
}

get_resource_by_host() {
  for item in `kubectl get node | awk '{print $1}' | grep -v NAME`; do

  echo -e "$item 资源状况为:"
    kubectl get pods --all-namespaces --field-selector spec.nodeName=$item -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}' | while read -r namespace pod; do kubectl top pod "$pod" -n "$namespace" --no-headers 2>/dev/null; done | awk '
  BEGIN {print "NAMESPACE", "NAME", "CPU(cores)", "MEMORY(GiB)"}
  {
      split($3, mem, "Mi");
      memory_gib = mem[1] / 1024;
      printf "%-20s %-50s %-10s %.2fGiB\n", $1, $2, $3, memory_gib;
      total += memory_gib;
  }
  END {printf "\nTOTAL MEMORY: %.2fGiB\n", total}' | column -t

  echo -e "\r\r"
  done
}